package com.itheima.service.mongo.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.itheima.domain.mongo.*;
import com.itheima.domain.vo.PageBeanVo;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.List;

@Service
public class MovementServiceImpl implements MovementService {

    //操作mongo
    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdService idService;
    /**
     * 保存我的动态
     * 1.保存动态详情表
     * 2.保存到个人动态表中
     * 3.查找好友关系
     * 4.保存到好友的朋友圈中
     * @param movement
     */
    @Override
    public void saveMovement(Movement movement) {
        //1.保存动态详情表
        //自己生成一个 ObjectId
        //ObjectId objectId = ObjectId.get();  -> 主动自己生成一个id
        movement.setCreated(System.currentTimeMillis());
        //等效 原来的 ++i
        movement.setPid( idService.getNextId(ConstantUtil.MOVEMENT_ID)); //主键自增的序列

        mongoTemplate.save(movement); //数据库自动生成的主键 程序中没有
        System.out.println("movement的id : "+  movement.getId() );

        //2.保存到个人动态表中 MyMovement
        MyMovement myMovement = new MyMovement();
        myMovement.setCreated(System.currentTimeMillis());//时间
        myMovement.setPublishId( movement.getId()  );  //发布的动态详情表中的主键id

        //保存我的动态
        mongoTemplate.save( myMovement , ConstantUtil.MOVEMENT_MINE + movement.getUserId() );

        //3.查找好友关系
        Query query = new Query(
                Criteria.where("userId").is(movement.getUserId())//查找我的朋友
        );
        List<Friend> friendList = mongoTemplate.find(query, Friend.class);
        //4.保存到好友的朋友圈中
        if(CollectionUtil.isNotEmpty(friendList)) {
            for (Friend friend : friendList) {
                FriendMovement friendMovement = new FriendMovement();
                friendMovement.setCreated(System.currentTimeMillis());
                friendMovement.setUserId(movement.getUserId());//发布动态人的id
                friendMovement.setPublishId( movement.getId() );  //发布的动态id
                //将数据发送到好友的动态表 中 使用的是好友的id
                mongoTemplate.save(friendMovement , ConstantUtil.MOVEMENT_FRIEND + friend.getFriendId());
            }
        }
    }

    /**
     * 查询我的动态
     * 1.根据userId 查询 我发布的所有动态 - 分页 (查询出来的是List<动态的id>)
     * 2.根据查询的所有动态的id  查询动态的详情信息
     * 3.构建返回值
     * 写代码的时候 考虑新老用户
     */
    @Override
    public PageBeanVo findMovementByUserId(Integer page, Integer pageSize, Long userId) {
        int startIndex = (page-1) * pageSize;
        //1.根据userId 查询 我发布的所有动态 - 分页 (查询出来的是List<动态的id>)
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("create")))//根据时间倒序
                .skip(startIndex).limit(pageSize);
        List<MyMovement> myMovementList = mongoTemplate.find(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);

        List<Movement> movementList = new ArrayList<>();
        //2.根据查询的所有动态的id  查询动态的详情信息
        if(CollectionUtil.isNotEmpty(myMovementList)){
            for (MyMovement myMovement : myMovementList) {

                //根据主键查询出动态详情对象
                Movement movement = mongoTemplate.findById(myMovement.getPublishId(), Movement.class);
                if(movement.getState()==1){
                    movementList.add(movement);//封装到集合
                }

            }
        }
        //查询总记录数
        long counts = mongoTemplate.count(query, ConstantUtil.MOVEMENT_MINE + userId);
        //3.构建返回值
        return new PageBeanVo(page , pageSize , counts ,  movementList);
    }

    /**
     * 查询好友动态
     * @param page
     * @param pageSize
     * @param loginUserId
     * @return
     */
    @Override
    public PageBeanVo findFriendMovement(Integer page, Integer pageSize, Long loginUserId) {
        int startIndex = (page-1) * pageSize;
        //1.根据userId 查询 查询好友发布的动态id
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("create")))//根据时间倒序
                .skip(startIndex).limit(pageSize);
        List<FriendMovement> friendMovementList = mongoTemplate.find(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + loginUserId);

        List<Movement> movementList = new ArrayList<>();
        //2.根据查询的所有动态的id  查询动态的详情信息
        if(CollectionUtil.isNotEmpty(friendMovementList)){
            for (FriendMovement friendMovement : friendMovementList) {
                //查询出每一条动态详情
                Movement movement = mongoTemplate.findById(friendMovement.getPublishId(), Movement.class);
                movementList.add(movement);
            }
        }
        //查询总记录数
        long counts = mongoTemplate.count(query, ConstantUtil.MOVEMENT_FRIEND + loginUserId);
        //3.构建返回值
        return new PageBeanVo(page , pageSize , counts ,  movementList);
    }

    @Override
    public PageBeanVo findRecommendMovement(Integer page, Integer pageSize, Long loginUserId) {
        int startIndex = (page-1) * pageSize;
        //1.根据userId 查询 查询推荐动态
        Query query = new Query(
                Criteria.where("userId").is(loginUserId)
        )
                .with(Sort.by(Sort.Order.desc("create")))//根据时间倒序
                .skip(startIndex).limit(pageSize);
        List<RecommendMovement> recommendMovementList = mongoTemplate.find(query, RecommendMovement.class);
        List<Movement> movementList = new ArrayList<>();


        //2.根据查询的所有动态的id  查询动态的详情信息
        if(CollectionUtil.isNotEmpty(recommendMovementList)){
            for (RecommendMovement recommendMovement : recommendMovementList) {
                //查询每一个动态的详细信息
                Movement movement = mongoTemplate.findById(recommendMovement.getPublishId(), Movement.class);
                movementList.add(movement);
            }
        }
        //查询总记录数
        long counts = mongoTemplate.count(query, RecommendMovement.class);
        //3.构建返回值
        return new PageBeanVo(page , pageSize , counts ,  movementList);
    }

    @Override
    public Movement findMovementByMovementId(String movementId) {
        Movement movement = mongoTemplate.findById(movementId, Movement.class);
        return movement;
    }

    /**
     * 查询个人的动态
     * 此方法是以后查询动态的时候 也需要使用此接口
     * @param uid
     * @param intState
     * @param page
     * @param pagesize
     * @return
     */
    @Override
    public PageBeanVo findByMessages(Long uid, Integer intState, Integer page, Integer pagesize) {
        int startIndex = (page-1)* pagesize;

        Query query = new Query(

        ).with(Sort.by(Sort.Order.desc("created"))).skip(startIndex).limit(pagesize);
        if(uid!=null){
            query.addCriteria(Criteria.where("userId").is(uid));
        }
        if(intState!=null){
            query.addCriteria(Criteria.where("state").is(intState));
        }
        List<Movement> movementList = mongoTemplate.find(query, Movement.class);
        long counts = mongoTemplate.count(query, Movement.class);
        return new PageBeanVo(page, pagesize , counts , movementList);
    }
}
